其他
通过ObRegisterCallbacks学习对象监控与反对象监控
本文为看雪论坛优秀文章
看雪论坛作者ID:1900
1
简介
2
对象监控
NTSTATUS
ObRegisterCallbacks(
IN POB_CALLBACK_REGISTRATION CallBackRegistration,
OUT PVOID *RegistrationHandle);
typedef struct _OB_CALLBACK_REGISTRATION {
__in USHORT Version;
__in USHORT OperationRegistrationCount;
__in UNICODE_STRING Altitude;
__in PVOID RegistrationContext;
__in OB_OPERATION_REGISTRATION *OperationRegistration;
} OB_CALLBACK_REGISTRATION, *POB_CALLBACK_REGISTRATION;
typedef struct _OB_OPERATION_REGISTRATION {
__in POBJECT_TYPE *ObjectType;
__in OB_OPERATION Operations;
__in POB_PRE_OPERATION_CALLBACK PreOperation;
__in POB_POST_OPERATION_CALLBACK PostOperation;
} OB_OPERATION_REGISTRATION, *POB_OPERATION_REGISTRATION;
OB_PREOP_CALLBACK_STATUS
ObjectPreCallback(
__in PVOID RegistrationContext,
__in POB_PRE_OPERATION_INFORMATION OperationInformation);
VOID
ObjectPostCallback(
__in PVOID RegistrationContext,
__in POB_POST_OPERATION_INFORMATION OperationInformation );
PEPROCESS
IoThreadToProcess(
IN PETHREAD Thread);
#include <ntifs.h>
#define PROCESS_NAME "demo.exe" // 要保护的进程名
#define PROCESS_TERMINATE 0x0001
typedef struct _KLDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID DllBase;
PVOID EntryPoint;
UINT32 SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
UINT32 Flags;
USHORT LoadCount;
USHORT TlsIndex;
LIST_ENTRY HashLinks;
PVOID SectionPointer;
UINT32 CheckSum;
UINT32 TimeDateStamp;
PVOID LoadedImports;
PVOID EntryPointActivationContext;
PVOID PatchInformation;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;
// 未导出函数声明
PUCHAR PsGetProcessImageFileName(PEPROCESS pEProcess);
VOID DriverUnload(IN PDRIVER_OBJECT driverObject);
BOOLEAN IsProtectProcess(PEPROCESS pEProcess); // 判断是否是要保护的进程
NTSTATUS SetProcessCallback(); // 设置进程回调函数
NTSTATUS SetThreadCallback(); // 设置线程回调函数
OB_PREOP_CALLBACK_STATUS ProcessPreCall(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION pObPreOperationInfo); // 进程回调函数
OB_PREOP_CALLBACK_STATUS ThreadPreCall(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION pObPreOperationInfo); // 线程回调函数
// 进程回调对象句柄
HANDLE g_obProcessHandle;
// 线程回调对象句柄
HANDLE g_obThreadHandle;
NTSTATUS DriverEntry(IN PDRIVER_OBJECT driverObject, IN PUNICODE_STRING registryPath)
{
NTSTATUS status = STATUS_SUCCESS;
PKLDR_DATA_TABLE_ENTRY pLdrData = NULL;
DbgPrint("驱动加载完成\r\n");
pLdrData = (PKLDR_DATA_TABLE_ENTRY)driverObject->DriverSection;
pLdrData->Flags = pLdrData->Flags | 0x20;
if (NT_SUCCESS(SetProcessCallback()))
{
DbgPrint("进程回调函数设置完成\r\n");
}
if (NT_SUCCESS(SetThreadCallback()))
{
DbgPrint("线程回调函数设置完成\r\n");
}
exit:
driverObject->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
NTSTATUS SetProcessCallback()
{
NTSTATUS status = STATUS_SUCCESS;
OB_CALLBACK_REGISTRATION obCallbackReg = { 0 };
OB_OPERATION_REGISTRATION obOperationReg = { 0 };
RtlZeroMemory(&obCallbackReg, sizeof(obCallbackReg));
RtlZeroMemory(&obOperationReg, sizeof(obOperationReg));
//设置OB_OPERATION_REGISTRATION
obOperationReg.ObjectType = PsProcessType;
obOperationReg.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
obOperationReg.PreOperation = (POB_PRE_OPERATION_CALLBACK)(&ProcessPreCall);
//设置OB_CALLBACK_REGISTRATION
obCallbackReg.Version = ObGetFilterVersion();
obCallbackReg.OperationRegistrationCount = 1;
obCallbackReg.RegistrationContext = NULL;
RtlInitUnicodeString(&obCallbackReg.Altitude, L"1900");
obCallbackReg.OperationRegistration = &obOperationReg;
status = ObRegisterCallbacks(&obCallbackReg, &g_obProcessHandle);
if (!NT_SUCCESS(status))
{
DbgPrint("ObRegisterCallbacks Error 0x%X\r\n", status);
}
return status;
}
OB_PREOP_CALLBACK_STATUS ProcessPreCall(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION pObPreOperationInfo)
{
PEPROCESS pEProcess = NULL;
// 判断对象类型
if (*PsProcessType != pObPreOperationInfo->ObjectType)
{
goto exit;
}
// 获取进程结构体对象
pEProcess = (PEPROCESS)pObPreOperationInfo->Object;
if (IsProtectProcess(pEProcess)) // 是否是要保护的进程
{
// 判断操作类型是创建句柄还是复制句柄
if (pObPreOperationInfo->Operation == OB_OPERATION_HANDLE_CREATE)
{
//是否具有关闭进程的权限,有的话删掉它
if (pObPreOperationInfo->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_TERMINATE)
{
pObPreOperationInfo->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_TERMINATE;
}
}
else if (pObPreOperationInfo->Operation == OB_OPERATION_HANDLE_DUPLICATE)
{
//是否具有关闭进程的权限,有的话删掉它
if (pObPreOperationInfo->Parameters->DuplicateHandleInformation.DesiredAccess & PROCESS_TERMINATE)
{
pObPreOperationInfo->Parameters->DuplicateHandleInformation.DesiredAccess &= ~PROCESS_TERMINATE;
}
}
}
exit:
return OB_PREOP_SUCCESS;
}
NTSTATUS SetThreadCallback()
{
NTSTATUS status = STATUS_SUCCESS;
OB_CALLBACK_REGISTRATION obCallbackReg = { 0 };
OB_OPERATION_REGISTRATION obOperationReg = { 0 };
RtlZeroMemory(&obCallbackReg, sizeof(OB_CALLBACK_REGISTRATION));
RtlZeroMemory(&obOperationReg, sizeof(OB_OPERATION_REGISTRATION));
// 设置 OB_OPERATION_REGISTRATION
obOperationReg.ObjectType = PsThreadType;
obOperationReg.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
obOperationReg.PreOperation = (POB_PRE_OPERATION_CALLBACK)(&ThreadPreCall);
// 设置 OB_CALLBACK_REGISTRATION
obCallbackReg.Version = ObGetFilterVersion();
obCallbackReg.OperationRegistrationCount = 1;
obCallbackReg.RegistrationContext = NULL;
RtlInitUnicodeString(&obCallbackReg.Altitude, L"1900");
obCallbackReg.OperationRegistration = &obOperationReg;
// 注册回调函数
status = ObRegisterCallbacks(&obCallbackReg, &g_obThreadHandle);
if (!NT_SUCCESS(status))
{
DbgPrint("ObRegisterCallbacks Error[0x%X]\n", status);
return status;
}
return status;
}
// 线程回调函数
OB_PREOP_CALLBACK_STATUS ThreadPreCall(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION pObPreOperationInfo)
{
PEPROCESS pEProcess = NULL;
// 判断对象类型
if (*PsThreadType != pObPreOperationInfo->ObjectType)
{
return OB_PREOP_SUCCESS;
}
// 获取线程对应的进程 PEPROCESS
pEProcess = IoThreadToProcess((PETHREAD)pObPreOperationInfo->Object);
// 判断是否是要保护的进程, 若是, 则拒绝结束线程
if (IsProtectProcess(pEProcess))
{
// 判断操作类型是创建句柄还是复制句柄
if (pObPreOperationInfo->Operation == OB_OPERATION_HANDLE_CREATE)
{
//是否具有关闭线程的权限,有的话删掉它
if (pObPreOperationInfo->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_TERMINATE)
{
pObPreOperationInfo->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_TERMINATE;
}
}
else if (pObPreOperationInfo->Operation == OB_OPERATION_HANDLE_DUPLICATE)
{
//是否具有关闭线程的权限,有的话删掉它
if (pObPreOperationInfo->Parameters->DuplicateHandleInformation.DesiredAccess & PROCESS_TERMINATE)
{
pObPreOperationInfo->Parameters->DuplicateHandleInformation.DesiredAccess &= ~PROCESS_TERMINATE;
}
}
}
return OB_PREOP_SUCCESS;
}
BOOLEAN IsProtectProcess(PEPROCESS pEProcess)
{
BOOLEAN bRet = FALSE;
PUCHAR pProcName = PsGetProcessImageFileName(pEProcess); // 获取要保护的进程名
if (pProcName)
{
if (strcmp(pProcName, PROCESS_NAME) == 0)
{
bRet = TRUE;
}
}
return bRet;
}
VOID DriverUnload(IN PDRIVER_OBJECT driverObject)
{
// 删除进程回调
if (g_obProcessHandle)
{
ObUnRegisterCallbacks(g_obProcessHandle);
g_obProcessHandle = NULL;
}
// 卸载线程回调
if (NULL != g_obThreadHandle)
{
ObUnRegisterCallbacks(g_obThreadHandle);
g_obThreadHandle = NULL;
}
DbgPrint("驱动卸载完成\r\n");
}
3
反对象监控
#pragma pack(1)
typedef struct _OB_CALLBACK
{
LIST_ENTRY ListEntry;
ULONGLONG Unknown;
HANDLE ObHandle;
PVOID ObTypeAddr;
PVOID PreCall;
PVOID PostCall;
}OB_CALLBACK, *POB_CALLBACK;
#pragma pack()
typedef struct _OBJECT_TYPE
{
LIST_ENTRY TypeList; // _LIST_ENTRY
UNICODE_STRING Name; // _UNICODE_STRING
PVOID DefaultObject; // Ptr64 Void
UCHAR Index; // UChar
ULONG TotalNumberOfObjects; // Uint4B
ULONG TotalNumberOfHandles; // Uint4B
ULONG HighWaterNumberOfObjects; // Uint4B
ULONG HighWaterNumberOfHandles; // Uint4B
OBJECT_TYPE_INITIALIZER TypeInfo; // _OBJECT_TYPE_INITIALIZER
EX_PUSH_LOCK TypeLock; // _EX_PUSH_LOCK
ULONG Key; // Uint4B
LIST_ENTRY CallbackList; // _LIST_ENTRY
}OBJECT_TYPE, *POBJECT_TYPE;
typedef struct _OBJECT_TYPE_INITIALIZER
{
USHORT Length; // Uint2B
UCHAR ObjectTypeFlags; // UChar
ULONG ObjectTypeCode; // Uint4B
ULONG InvalidAttributes; // Uint4B
GENERIC_MAPPING GenericMapping; // _GENERIC_MAPPING
ULONG ValidAccessMask; // Uint4B
ULONG RetainAccess; // Uint4B
POOL_TYPE PoolType; // _POOL_TYPE
ULONG DefaultPagedPoolCharge; // Uint4B
ULONG DefaultNonPagedPoolCharge; // Uint4B
PVOID DumpProcedure; // Ptr64 void
PVOID OpenProcedure; // Ptr64 long
PVOID CloseProcedure; // Ptr64 void
PVOID DeleteProcedure; // Ptr64 void
PVOID ParseProcedure; // Ptr64 long
PVOID SecurityProcedure; // Ptr64 long
PVOID QueryNameProcedure; // Ptr64 long
PVOID OkayToCloseProcedure; // Ptr64 unsigned char
#if (NTDDI_VERSION >= NTDDI_WINBLUE) // Win8.1
ULONG WaitObjectFlagMask; // Uint4B
USHORT WaitObjectFlagOffset; // Uint2B
USHORT WaitObjectPointerOffset; // Uint2B
#endif
}OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;
#include <ntifs.h>
#include <wdm.h>
#pragma pack(1)
typedef struct _OBJECT_TYPE_INITIALIZER
{
USHORT Length; // Uint2B
UCHAR ObjectTypeFlags; // UChar
ULONG ObjectTypeCode; // Uint4B
ULONG InvalidAttributes; // Uint4B
GENERIC_MAPPING GenericMapping; // _GENERIC_MAPPING
ULONG ValidAccessMask; // Uint4B
ULONG RetainAccess; // Uint4B
POOL_TYPE PoolType; // _POOL_TYPE
ULONG DefaultPagedPoolCharge; // Uint4B
ULONG DefaultNonPagedPoolCharge; // Uint4B
PVOID DumpProcedure; // Ptr64 void
PVOID OpenProcedure; // Ptr64 long
PVOID CloseProcedure; // Ptr64 void
PVOID DeleteProcedure; // Ptr64 void
PVOID ParseProcedure; // Ptr64 long
PVOID SecurityProcedure; // Ptr64 long
PVOID QueryNameProcedure; // Ptr64 long
PVOID OkayToCloseProcedure; // Ptr64 unsigned char
#if (NTDDI_VERSION >= NTDDI_WINBLUE) // Win8.1
ULONG WaitObjectFlagMask; // Uint4B
USHORT WaitObjectFlagOffset; // Uint2B
USHORT WaitObjectPointerOffset; // Uint2B
#endif
}OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;
typedef struct _OBJECT_TYPE
{
LIST_ENTRY TypeList; // _LIST_ENTRY
UNICODE_STRING Name; // _UNICODE_STRING
PVOID DefaultObject; // Ptr64 Void
UCHAR Index; // UChar
ULONG TotalNumberOfObjects; // Uint4B
ULONG TotalNumberOfHandles; // Uint4B
ULONG HighWaterNumberOfObjects; // Uint4B
ULONG HighWaterNumberOfHandles; // Uint4B
OBJECT_TYPE_INITIALIZER TypeInfo; // _OBJECT_TYPE_INITIALIZER
EX_PUSH_LOCK TypeLock; // _EX_PUSH_LOCK
ULONG Key; // Uint4B
LIST_ENTRY CallbackList; // _LIST_ENTRY
}OBJECT_TYPE, *POBJECT_TYPE;
typedef struct _OB_CALLBACK
{
LIST_ENTRY ListEntry;
ULONGLONG Unknown;
HANDLE ObHandle;
PVOID ObTypeAddr;
PVOID PreCall;
PVOID PostCall;
}OB_CALLBACK, *POB_CALLBACK;
#pragma pack()
VOID DriverUnload(IN PDRIVER_OBJECT driverObject);
BOOLEAN RemoveProcessObCallback();
BOOLEAN RemoveThreadObCallback();
NTSTATUS DriverEntry(IN PDRIVER_OBJECT driverObject, IN PUNICODE_STRING registryPath)
{
NTSTATUS status = STATUS_SUCCESS;
if (RemoveProcessObCallback())
{
DbgPrint("删除进程回调成功\r\n");
}
else
{
DbgPrint("删除进程回调失败\r\n");
}
if (RemoveThreadObCallback())
{
DbgPrint("删除线程回调成功\r\n");
}
else
{
DbgPrint("删除线程回调失败\r\n");
}
exit:
driverObject->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
BOOLEAN RemoveThreadObCallback()
{
BOOLEAN bRet = TRUE;
LIST_ENTRY CallbackList = ((POBJECT_TYPE)(*PsProcessType))->CallbackList; // 获取线程表头
POB_CALLBACK pObCallback = NULL;
pObCallback = (POB_CALLBACK)CallbackList.Flink;
do{
if (!MmIsAddressValid(pObCallback))
{
bRet = FALSE;
break;
}
if (pObCallback->ObHandle)
{
ObUnRegisterCallbacks(pObCallback->ObHandle);
DbgPrint("删除回调函数成功,函数地址:0x%X\r\n", pObCallback->PreCall);
}
} while (CallbackList.Flink != (PLIST_ENTRY)pObCallback);
return bRet;
}
BOOLEAN RemoveProcessObCallback()
{
BOOLEAN bRet = TRUE;
POB_CALLBACK pObCallback = NULL;
LIST_ENTRY CallbackList = ((POBJECT_TYPE)(*PsProcessType))->CallbackList; // 获取设置进程对象回调函数的双向链表表头
pObCallback = (POB_CALLBACK)CallbackList.Flink;
do{
if (!MmIsAddressValid(pObCallback))
{
bRet = FALSE;
break;
}
if (pObCallback->ObHandle)
{
ObUnRegisterCallbacks(pObCallback->ObHandle);
DbgPrint("删除回调成功,函数地址为:0x%X\r\n", pObCallback->PreCall);
}
pObCallback = (POB_CALLBACK)pObCallback->ListEntry.Flink;
}while (CallbackList.Flink != (PLIST_ENTRY)pObCallback);
return bRet;
}
VOID DriverUnload(IN PDRIVER_OBJECT driverObject)
{
DbgPrint("驱动卸载完成\r\n");
}
4
运行结果
看雪ID:1900
https://bbs.pediy.com/user-home-835440.htm
# 往期推荐
4.通过CmRegisterCallback学习注册表监控与反注册表监控
5.Android APP漏洞之战——权限安全和安全配置漏洞详解
6.全网最详细CVE-2014-0502 Adobe Flash Player双重释放漏洞分析
球分享
球点赞
球在看
点击“阅读原文”,了解更多!